package analiseSintatica.Regras.Expressoes;

import analiseSintatica.Regras.*;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.ErroSemantico;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import java.util.LinkedList;

/**
 *
 * @author linton
 * @author nathy
 */
public class RegraIgualdade extends Regra {

    protected static Regra instancia;
//<igualdade> ::= <relacional> {<op_igualdade> <relacional>}
    protected String estrutura = "<relacional> {<op_igualdade> <relacional>}";
    RegraRelacional regraRelacional =  RegraRelacional.getInstance();
    RegraOpIgualdade regraOpIguadade = RegraOpIgualdade.getInstance();


    /**
     * Construtor privado necessario ao singleton
     */
    private RegraIgualdade() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraIgualdade getInstance() {
        if (instancia == null) {
            instancia = new RegraIgualdade();
        }
        return (RegraIgualdade) instancia;
    }

  //  @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
       
    	TiposSemanticos retorno;

        TiposSemanticos regra1Tipos = RegraRelacional.getInstance().analisar(listaTokens);
        
        retorno = regra1Tipos;

        while(listaContem(RegraOpIgualdade.getInstance().getPrimeiro(), listaTokens.getFirst())){
        	
            RegraOpIgualdade.getInstance().analisar(listaTokens);
            TiposSemanticos regra2Tipos = RegraRelacional.getInstance().analisar(listaTokens);

           if(retorno != null && regra2Tipos != null){
        	   TipoSemantico regra2 = regra2Tipos.getFirst();

        	   	int linha = regra2.getLinha();

				if(!regra2Tipos.getFirst().getNomeTipo().equals(retorno.getFirst().getNomeTipo())){
				    String frase = "Comparacao entre tipos diferentes: "+retorno.getFirst().getNomeTipo() + " \te "+regra2.getNomeTipo();
				    AnalisadorSintatico.errosemanticos.add(new ErroSemantico(frase,linha));
				    retorno = null;
				}else{
					//Essa regraIgualdade retorna um tipo booleano no caso
		            //de houver comparacao de igualdade
		            TiposSemanticos tipoReturn = new TiposSemanticos();
		            tipoReturn .addTipos(new TipoSemantico("boolean",linha));
		            retorno = tipoReturn;
				}

            }else{
            	retorno = null;
            }
        } 
        return retorno;
    }    

    @Override
    protected void setPrimeiro() {
        this.primeiro = RegraRelacional.getInstance().getPrimeiro();

    }
}
